const http = require('http');

/**
 * 考试系统并发性能测试
 * 使用方法: node performance-test.js
 */

// 测试配置
const config = {
  baseUrl: 'http://localhost:3000',
  endpoints: [
    '/health',                    // 健康检查
  ],
  concurrentUsers: [10, 50, 100, 200, 500, 1000], // 并发用户数
  requestsPerUser: 5,            // 每个用户发送的请求数
  timeout: 10000,               // 超时时间（毫秒）
};

/**
 * 执行HTTP请求
 */
function makeRequest(url, options = {}) {
  return new Promise((resolve, reject) => {
    const startTime = Date.now();
    
    const req = http.request(url, {
      method: options.method || 'GET',
      headers: {
        'Content-Type': 'application/json',
        'User-Agent': 'Performance-Test-Script',
        ...options.headers
      },
      timeout: config.timeout,
    }, (res) => {
      let data = '';
      res.on('data', chunk => data += chunk);
      res.on('end', () => {
        const endTime = Date.now();
        resolve({
          statusCode: res.statusCode,
          responseTime: endTime - startTime,
          dataLength: data.length,
          success: res.statusCode >= 200 && res.statusCode < 300
        });
      });
    });

    req.on('error', (error) => {
      const endTime = Date.now();
      reject({
        error: error.message,
        responseTime: endTime - startTime,
        success: false
      });
    });

    req.on('timeout', () => {
      req.destroy();
      reject({
        error: 'Request timeout',
        responseTime: config.timeout,
        success: false
      });
    });

    if (options.data) {
      req.write(JSON.stringify(options.data));
    }
    
    req.end();
  });
}

/**
 * 执行单个并发测试
 */
async function runConcurrentTest(concurrentUsers, endpoint) {
  console.log(`\n📊 测试端点: ${endpoint}`);
  console.log(`👥 并发用户数: ${concurrentUsers}`);
  console.log(`📨 每用户请求数: ${config.requestsPerUser}`);
  console.log(`🎯 总请求数: ${concurrentUsers * config.requestsPerUser}`);
  
  const startTime = Date.now();
  
  // 创建并发请求
  const promises = [];
  for (let user = 0; user < concurrentUsers; user++) {
    for (let req = 0; req < config.requestsPerUser; req++) {
      promises.push(
        makeRequest(`${config.baseUrl}${endpoint}`)
          .then(result => ({ user, request: req, ...result }))
          .catch(error => ({ user, request: req, ...error, success: false }))
      );
    }
  }
  
  // 等待所有请求完成
  const results = await Promise.allSettled(promises);
  const endTime = Date.now();
  
  // 统计结果
  const successfulRequests = results.filter(r => r.status === 'fulfilled' && r.value.success);
  const failedRequests = results.filter(r => r.status === 'rejected' || (r.status === 'fulfilled' && !r.value.success));
  const responseTimes = successfulRequests.map(r => r.value.responseTime);
  
  const stats = {
    totalRequests: results.length,
    successfulRequests: successfulRequests.length,
    failedRequests: failedRequests.length,
    successRate: (successfulRequests.length / results.length * 100).toFixed(2),
    totalTime: endTime - startTime,
    requestsPerSecond: (results.length / ((endTime - startTime) / 1000)).toFixed(2),
    avgResponseTime: responseTimes.length > 0 ? (responseTimes.reduce((a, b) => a + b, 0) / responseTimes.length).toFixed(2) : 0,
    minResponseTime: responseTimes.length > 0 ? Math.min(...responseTimes) : 0,
    maxResponseTime: responseTimes.length > 0 ? Math.max(...responseTimes) : 0,
    percentile95: responseTimes.length > 0 ? getPercentile(responseTimes, 95).toFixed(2) : 0,
    concurrentUsers,
    endpoint
  };
  
  return stats;
}

/**
 * 计算百分位数
 */
function getPercentile(arr, percentile) {
  const sorted = arr.slice().sort((a, b) => a - b);
  const index = Math.ceil((percentile / 100) * sorted.length) - 1;
  return sorted[index];
}

/**
 * 主测试函数
 */
async function runPerformanceTest() {
  console.log('🚀 考试系统并发性能测试');
  console.log('📋 测试配置:', {
    并发级别: config.concurrentUsers,
    每用户请求数: config.requestsPerUser,
    超时时间: config.timeout + 'ms'
  });
  console.log('='.repeat(60));
  
  const allResults = [];
  
  // 首先检查服务是否可用
  try {
    console.log('\n🔍 检查服务可用性...');
    const healthCheck = await makeRequest(`${config.baseUrl}/health`);
    if (healthCheck.success) {
      console.log('✅ 服务运行正常，开始性能测试');
    } else {
      console.log('❌ 服务不可用，请检查后端是否正常运行');
      return;
    }
  } catch (error) {
    console.log('❌ 无法连接到服务，请检查后端是否正常运行');
    console.error('错误:', error.error || error.message);
    return;
  }
  
  // 测试不同的并发级别
  for (const concurrentUsers of config.concurrentUsers) {
    try {
      const result = await runConcurrentTest(concurrentUsers, '/health');
      allResults.push(result);
      
      // 显示结果
      console.log(`\n✅ 并发${concurrentUsers}用户测试完成:`);
      console.log(`   成功率: ${result.successRate}%`);
      console.log(`   成功请求: ${result.successfulRequests}/${result.totalRequests}`);
      console.log(`   平均响应时间: ${result.avgResponseTime}ms`);
      console.log(`   95%响应时间: ${result.percentile95}ms`);
      console.log(`   最大响应时间: ${result.maxResponseTime}ms`);
      console.log(`   吞吐量: ${result.requestsPerSecond} RPS`);
      
      // 性能评估
      const successRate = parseFloat(result.successRate);
      const avgTime = parseFloat(result.avgResponseTime);
      
      let performanceLevel = '';
      if (successRate >= 99 && avgTime < 100) {
        performanceLevel = '🟢 优秀';
      } else if (successRate >= 95 && avgTime < 500) {
        performanceLevel = '🟡 良好';
      } else if (successRate >= 80) {
        performanceLevel = '🟠 一般';
      } else {
        performanceLevel = '🔴 需要优化';
      }
      
      console.log(`   性能评级: ${performanceLevel}`);
      
      // 如果成功率低于80%，建议停止测试
      if (successRate < 80) {
        console.log(`⚠️  警告: 成功率过低，可能已达到系统极限`);
        break;
      }
      
      // 在测试之间稍作休息，让系统恢复
      if (concurrentUsers < 1000) {
        console.log('   ⏳ 等待系统恢复...');
        await new Promise(resolve => setTimeout(resolve, 3000));
      }
      
    } catch (error) {
      console.error(`❌ 测试失败:`, error);
      break;
    }
  }
  
  // 生成详细报告
  console.log('\n📊 性能测试报告');
  console.log('='.repeat(80));
  console.log('并发用户 | 成功率  | 平均响应 | 95%响应 | 最大响应 | 吞吐量  | 评级');
  console.log('-'.repeat(80));
  
  allResults.forEach(result => {
    const successRate = parseFloat(result.successRate);
    const avgTime = parseFloat(result.avgResponseTime);
    
    let status = '';
    if (successRate >= 99 && avgTime < 100) {
      status = '🟢 优秀';
    } else if (successRate >= 95 && avgTime < 500) {
      status = '🟡 良好';
    } else if (successRate >= 80) {
      status = '🟠 一般';
    } else {
      status = '🔴 差';
    }
    
    console.log(
      `${result.concurrentUsers.toString().padStart(8)} | ` +
      `${result.successRate.padStart(6)}% | ` +
      `${result.avgResponseTime.padStart(7)}ms | ` +
      `${result.percentile95.padStart(6)}ms | ` +
      `${result.maxResponseTime.padStart(7)}ms | ` +
      `${result.requestsPerSecond.padStart(6)} | ` +
      `${status}`
    );
  });
  
  // 找出最佳性能点
  const bestResult = allResults.find(r => parseFloat(r.successRate) >= 95);
  if (bestResult) {
    console.log(`\n🎯 推荐并发配置:`);
    console.log(`   最大并发用户数: ${bestResult.concurrentUsers}`);
    console.log(`   预期吞吐量: ${bestResult.requestsPerSecond} RPS`);
    console.log(`   平均响应时间: ${bestResult.avgResponseTime}ms`);
  }
  
  console.log('\n💡 优化建议:');
  console.log('1. 🔧 当前MongoDB连接池已优化到50个连接');
  console.log('2. 🚀 可考虑使用PM2集群模式运行多个进程');
  console.log('3. 📊 监控系统资源使用情况(CPU、内存、网络)');
  console.log('4. 🗄️  对频繁查询的数据考虑添加缓存层');
  console.log('5. 📈 使用负载均衡器分发请求到多个服务实例');
  
  console.log('\n测试完成! 🎉');
}

// 运行测试
if (require.main === module) {
  runPerformanceTest().catch(console.error);
}

module.exports = { runPerformanceTest };
